package com.yaoandw.lucene;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;
import com.yaoandw.givebook.Constants;
import com.yaoandw.util.StringUtil;

public class PageSearcher {
	public static void main(String[] args) throws IllegalArgumentException,
			IOException, ParseException {
		String q = "斗破苍穹";
		search(Constants.indexDir, q);
	}

	public static void search(String indexDir, String q) throws IOException, ParseException {
		PageSearcher searcher = PageSearcher.getInstance(indexDir);
		Result result = searcher.search(q, 1, 10);
		for(RecordResult recordResult : result.getResults()){
			System.out.println("=====================");
			System.out.println(recordResult);
		}
	}
	private static PageSearcher pageSearcher;
	private String indexDir;
	private PageSearcher(String indexDir){
		this.indexDir = indexDir;
	}
	public static PageSearcher getInstance(String indexDir){
		if(pageSearcher == null)
			pageSearcher = new PageSearcher(indexDir);
		return pageSearcher;
	}
	/**
	 * @param q
	 * @param pageNo 第几页
	 * @param pageSize 每页条数
	 * @return
	 * @throws IOException
	 * @throws ParseException
	 */
	public Result search(String q,int pageNo,int pageSize) throws IOException, ParseException {
		long start = System.currentTimeMillis();
		List<RecordResult> results = new ArrayList<RecordResult>();
		Directory dir = FSDirectory.open(new File(indexDir));
		 IndexReader reader = DirectoryReader.open(dir);
		IndexSearcher is = new IndexSearcher(reader);
		Analyzer analyzer = new MMSegAnalyzer();
//		QueryParser parser = new QueryParser(Version.LUCENE_34, "contents",	analyzer);
		QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_42, new String[]{"title","contents"},	analyzer);
		Query query = parser.parse(q);
//		Term t = new Term("contents", q);
//        Query query = new TermQuery(t);
		int fetchCnt = pageNo*pageSize;
		TopDocs hits = is.search(query, fetchCnt);
		int totalCnt = hits.totalHits;
		//high light
		SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");   
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));    
        highlighter.setTextFragmenter(new SimpleFragmenter(60));
        int realCnt = totalCnt<fetchCnt?totalCnt:fetchCnt;
        ScoreDoc[] docs = hits.scoreDocs;
        for( int i = (pageNo-1)*10+1;i<=realCnt;i++){
        	ScoreDoc scoreDoc = docs[i-1];
//		for (ScoreDoc scoreDoc : hits.scoreDocs) {
			String title = "";
			String content = "";
			String link = "";
			String time = "";
			String txtFileLink = "";
			Document doc = is.doc(scoreDoc.doc);
//			//high light
			content = doc.get("contents");   
			link = doc.get("fullpath");
			title = doc.get("title");
			time = doc.get("crawltime");
			txtFileLink = doc.get("txtpath");
            if (content != null) {    
                TokenStream tokenStream1 = analyzer.tokenStream("contents",new StringReader(content));    
                TokenStream tokenStream2 = analyzer.tokenStream("title",new StringReader(title));    
				try {
					String tempContent = highlighter.getBestFragments(tokenStream1, content,2,"<br>");
					if(!StringUtil.isEmpty(tempContent))
						content = tempContent;
					String tempTitle = highlighter.getBestFragment(tokenStream2, title);
					if(!StringUtil.isEmpty(tempTitle))
						title = tempTitle;
				} catch (InvalidTokenOffsetsException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
            } 
            if(!StringUtil.isEmpty(title)&&!StringUtil.isEmpty(content)&&!StringUtil.isEmpty(link)&&!StringUtil.isEmpty(time)){
            	RecordResult recordResult = new RecordResult(title,content,link,time,txtFileLink);
            	results.add(recordResult);
            }
		}
        reader.close();
        dir.close();
		long end = System.currentTimeMillis();
		double cost = ((double)end-(double)start)/1000;
		System.err.println("Found " + totalCnt + " document(s) (in "
				+ cost + " seconds) that matched query '" + q
				+ "':");
		return new Result(totalCnt,results,cost);
	}
}